package com.zmn.plat.business.impl.brand.ratio;

import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.plat.business.interfaces.brand.ratio.BrandRatioBService;
import com.zmn.plat.common.constant.ProductConsts;
import com.zmn.plat.common.dictionary.BaseBrandPriceTypeEnum;
import com.zmn.plat.common.dictionary.BaseBrandRatioTypeEnum;
import com.zmn.plat.common.dto.brand.factor.BrandFactorDRO;
import com.zmn.plat.common.exception.PlatException;
import com.zmn.plat.model.entity.brand.BaseBrand;
import com.zmn.plat.model.entity.brand.BrandRatio;
import com.zmn.plat.model.entity.brand.BrandRatioQuery;
import com.zmn.plat.model.entity.category.BaseCategory;
import com.zmn.plat.model.entity.product.ServProduct;
import com.zmn.plat.model.entity.servcategory.ServCategory;
import com.zmn.plat.model.vo.brand.BrandRatioModifyVo;
import com.zmn.plat.model.vo.brand.BrandRatioVo;
import com.zmn.plat.model.vo.brand.factor.BrandFactorCategoryRatioVo;
import com.zmn.plat.model.vo.brand.factor.BrandFactorVo;
import com.zmn.plat.services.interfaces.brand.BaseBrandService;
import com.zmn.plat.services.interfaces.brand.BrandRatioService;
import com.zmn.plat.services.interfaces.category.BaseCategoryService;
import com.zmn.plat.services.interfaces.product.ServProductService;
import com.zmn.plat.services.interfaces.servcategory.ServAssCategoryService;
import com.zmn.plat.services.interfaces.servcategory.ServCategoryService;

/**
 * @author linfeng
 * @since 2019/11/23/15:05
 */
@Service
public class BrandRatioBServiceImpl implements BrandRatioBService {
    private Logger logger = LoggerFactory.getLogger(BrandRatioBServiceImpl.class);

    @Resource
    BrandRatioService brandRatioService;
    @Resource
    ServAssCategoryService servAssCategoryService;
    @Resource
    BaseCategoryService baseCategoryService;
    @Resource
    ServCategoryService servCategoryService;
    @Resource
    BaseBrandService baseBrandService;

    @Autowired
    private ServProductService servProductService;

    @Override
    public BrandFactorDRO findByProductId(Integer brandId, Integer productId, Integer type) {
        return getByBrandIdAndProductIdAndBizTypeAndPriceType(brandId, productId, type, BaseBrandPriceTypeEnum.PRICE.getCode());
    }

    @Override
    @Cacheable(cacheNames = "redis1d", key = "'base:ratio:brandId:'+#p0+':showProductId:'+#p1+':type:'+#p2+':priceType:'+#p3", unless = "#result == null")
    public BrandFactorDRO getByBrandIdAndProductIdAndBizTypeAndPriceType(Integer brandId, Integer showProductId, Integer type, Integer priceType) {
        logger.debug("getByBrandIdAndShowProductIdAndKeepType params is:{},{},{}", brandId, showProductId, type);
        ServProduct product = servProductService.findByKeyWithCache(showProductId);
        if (product == null) {
            logger.error("product is not exists");
            return null;
        }
        BeanCopier copier = BeanCopier.create(BrandFactorVo.class, BrandFactorDRO.class, false);
        BrandFactorDRO dro = new BrandFactorDRO();
        // 设置默认值
        BrandFactorVo retVo = defaultRatio(product, brandId, type);
        // 品牌系数取系数的顺序为：产品系数->产品二级分类的系数->产品一级分类的系数->服务分类的系数->默认的系数；取到系数就不再往下取

        // 产品二级分类的系数
        BrandRatioQuery query = new BrandRatioQuery();
        query.setBrandId(brandId);
        query.setBizType(type);
        query.setPriceType(priceType);
        query.setServCategId(product.getServCategId());
        query.setCategOneId(product.getCategOneId());
        query.setCategId(product.getCategId());
        query.setRatioType(BaseBrandRatioTypeEnum.BRANDCATEGTWORATIO.getCode());

        BrandRatio brandRatio = null;
        List<BrandRatio> brandRatios = brandRatioService.listByQueryWithCache(query);
        if (brandRatios != null && brandRatios.size() > 0) {
            brandRatio = brandRatios.get(0);
        }

        if (null != brandRatio) {
            if (brandRatio.getRatio() != null) {
                logger.debug("产品二级分类的系数不为空，取配置的产品二级分类系数 {}", brandRatio);
                retVo.setRatio(brandRatio.getRatio());
                copier.copy(retVo, dro, null);
                return dro;
            }
        }
        // 产品一级分类的系数
        query.setCategId(null);
        query.setRatioType(BaseBrandRatioTypeEnum.BRANDCATEGONERATIO.getCode());
        brandRatios = brandRatioService.listByQueryWithCache(query);
        if (brandRatios != null && brandRatios.size() > 0) {
            brandRatio = brandRatios.get(0);
        } else {
            brandRatio = null;
        }
        if (null != brandRatio) {
            if (brandRatio.getRatio() != null) {
                logger.debug("产品一级分类的系数不为空，取配置的产品一级分类 {}", brandRatio);
                retVo.setRatio(brandRatio.getRatio());
                copier.copy(retVo, dro, null);
                return dro;
            }
        }
        // 默认的系数
        query.setCategId(null);
        query.setCategOneId(null);
        query.setServCategId(null);
        query.setRatioType(BaseBrandRatioTypeEnum.BRANDRATIO.getCode());
        brandRatios = brandRatioService.listByQueryWithCache(query);
        if (brandRatios != null && brandRatios.size() > 0) {
            brandRatio = brandRatios.get(0);
        } else {
            brandRatio = null;
        }
        if (null != brandRatio) {
            if (brandRatio.getRatio() != null) {
                logger.debug("默认的系数不为空，取配置的默认的系数 {}", brandRatio);
                retVo.setRatio(brandRatio.getRatio());
                copier.copy(retVo, dro, null);
                return dro;
            }
        }
        copier.copy(retVo, dro, null);
        logger.debug("所有系数都未配置，retVo={}", dro);
        // 都不存在的情况下，返回1
        return dro;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer addEditBrandRatio(String mcStaffName, BrandRatioVo brandRatioVo) throws PlatException {
        Date now = DateUtil.getNow();

        BrandRatioQuery brandRatioQuery = new BrandRatioQuery();
        brandRatioQuery.setBrandId(brandRatioVo.getBrandId());
        brandRatioQuery.setRatioType(BaseBrandRatioTypeEnum.BRANDRATIO.getCode());
        brandRatioQuery.setPriceType(brandRatioVo.getPriceType());
        List<BrandRatio> brandRatios = brandRatioService.listByQuery(brandRatioQuery);

        // 新增的时候需要判断品牌是否已经添加过系数
        if (brandRatios != null && brandRatios.size() > 0 && brandRatioVo.getAddFlag()) {
            BaseBrand baseBrand = baseBrandService.findByKey(brandRatioVo.getBrandId());
            String brandName = baseBrand == null ? "" : baseBrand.getName();
            logger.error("已存在【{}】品牌，请在对应的品牌下设置品牌系数！", brandName);
            throw new PlatException("已存在【" + brandName + "】品牌，请在对应的品牌下设置品牌系数！");
        }

        BrandRatio brandRatioC = findBrandRatioByBrandIdAndPriceTypeAndBizType(brandRatioVo.getBrandId(), brandRatioVo.getPriceType(), ProductConsts.BIZ_TYPE_C);
        BrandRatio brandRatioF = findBrandRatioByBrandIdAndPriceTypeAndBizType(brandRatioVo.getBrandId(), brandRatioVo.getPriceType(), ProductConsts.BIZ_TYPE_F);
        BrandRatio brandRatioB = findBrandRatioByBrandIdAndPriceTypeAndBizType(brandRatioVo.getBrandId(), brandRatioVo.getPriceType(), ProductConsts.BIZ_TYPE_B);

        try {
            brandRatioQuery.setRatioType(BaseBrandRatioTypeEnum.BRANDMETER3RATIO.getCode());
            List<BrandRatio> brandRatioMeterList = brandRatioService.listByQuery(brandRatioQuery);
            BrandRatio brandRatioM = null;
            if (CollectionUtil.isNotNullOrEmpty(brandRatioMeterList)) {
                brandRatioM = brandRatioMeterList.get(0);
            }
            if (Objects.isNull(brandRatioM)) {
                if (brandRatioVo.getBrandMeterToBeEffectiveRatio() != null) {
                    BrandRatio createBrandRatio = new BrandRatio();
                    BeanUtils.copyProperties(brandRatioVo, createBrandRatio);
                    createBrandRatio.setToBeEffectiveRatio(brandRatioVo.getBrandMeterToBeEffectiveRatio());
                    createBrandRatio.setEffectiveDate(brandRatioVo.getEffectiveDate());
                    createBrandRatio.setCreater(mcStaffName);
                    createBrandRatio.setCreateTime(now);
                    createBrandRatio.setUpdater(mcStaffName);
                    createBrandRatio.setUpdateTime(now);
                    createBrandRatio.setRatioType(BaseBrandRatioTypeEnum.BRANDMETER3RATIO.getCode());
                    brandRatioService.insert(createBrandRatio);
                }
            } else {
                if (brandRatioM.getRatio() == null && brandRatioVo.getBrandMeterToBeEffectiveRatio() == null) {
                    brandRatioService.deleteByPrimaryKey(brandRatioM.getRatioId());
                } else {
                    brandRatioM.setToBeEffectiveRatio(brandRatioVo.getBrandMeterToBeEffectiveRatio());
                    brandRatioM.setEffectiveDate(brandRatioVo.getEffectiveDate());
                    brandRatioM.setUpdateTime(DateUtil.getNow());
                    brandRatioM.setUpdater(mcStaffName);
                    brandRatioService.updateByKey(brandRatioM);
                }
            }

            if (brandRatioC == null) {
                if (brandRatioVo.getBrandOutToBeEffectiveRatio() != null) {
                    BrandRatio createBrandRatio = new BrandRatio();
                    BeanUtils.copyProperties(brandRatioVo, createBrandRatio);
                    createBrandRatio.setBizType(ProductConsts.BIZ_TYPE_C);
                    createBrandRatio.setToBeEffectiveRatio(brandRatioVo.getBrandOutToBeEffectiveRatio());
                    createBrandRatio.setEffectiveDate(brandRatioVo.getEffectiveDate());
                    createBrandRatio.setCreater(mcStaffName);
                    createBrandRatio.setCreateTime(now);
                    createBrandRatio.setUpdater(mcStaffName);
                    createBrandRatio.setUpdateTime(now);
                    createBrandRatio.setRatioType(BaseBrandRatioTypeEnum.BRANDRATIO.getCode());
                    brandRatioService.insert(createBrandRatio);
                }
            } else {
                if (brandRatioC.getRatio() == null && brandRatioVo.getBrandOutToBeEffectiveRatio() == null) {
                    brandRatioService.deleteByPrimaryKey(brandRatioC.getRatioId());
                } else {
                    brandRatioC.setToBeEffectiveRatio(brandRatioVo.getBrandOutToBeEffectiveRatio());
                    brandRatioC.setEffectiveDate(brandRatioVo.getEffectiveDate());
                    brandRatioC.setUpdateTime(DateUtil.getNow());
                    brandRatioC.setUpdater(mcStaffName);
                    brandRatioService.updateByKey(brandRatioC);
                }
            }

            if (brandRatioF == null) {
                if (brandRatioVo.getBrandInToBeEffectiveRatio() != null) {
                    BrandRatio createBrandRatio = new BrandRatio();
                    BeanUtils.copyProperties(brandRatioVo, createBrandRatio);
                    createBrandRatio.setBizType(ProductConsts.BIZ_TYPE_F);
                    createBrandRatio.setToBeEffectiveRatio(brandRatioVo.getBrandInToBeEffectiveRatio());
                    createBrandRatio.setEffectiveDate(brandRatioVo.getEffectiveDate());
                    createBrandRatio.setCreater(mcStaffName);
                    createBrandRatio.setCreateTime(now);
                    createBrandRatio.setUpdater(mcStaffName);
                    createBrandRatio.setUpdateTime(now);
                    createBrandRatio.setRatioType(BaseBrandRatioTypeEnum.BRANDRATIO.getCode());
                    brandRatioService.insert(createBrandRatio);
                }
            } else {
                if (brandRatioF.getRatio() == null && brandRatioVo.getBrandInToBeEffectiveRatio() == null) {
                    brandRatioService.deleteByPrimaryKey(brandRatioF.getRatioId());
                } else {
                    brandRatioF.setToBeEffectiveRatio(brandRatioVo.getBrandInToBeEffectiveRatio());
                    brandRatioF.setEffectiveDate(brandRatioVo.getEffectiveDate());
                    brandRatioF.setUpdateTime(DateUtil.getNow());
                    brandRatioF.setUpdater(mcStaffName);
                    brandRatioService.updateByKey(brandRatioF);
                }
            }

            if (brandRatioB == null) {
                if (brandRatioVo.getBrandProjectToBeEffectiveRatio() != null) {
                    BrandRatio createBrandRatio = new BrandRatio();
                    BeanUtils.copyProperties(brandRatioVo, createBrandRatio);
                    createBrandRatio.setBizType(ProductConsts.BIZ_TYPE_B);
                    createBrandRatio.setToBeEffectiveRatio(brandRatioVo.getBrandProjectToBeEffectiveRatio());
                    createBrandRatio.setEffectiveDate(brandRatioVo.getEffectiveDate());
                    createBrandRatio.setCreater(mcStaffName);
                    createBrandRatio.setCreateTime(now);
                    createBrandRatio.setUpdater(mcStaffName);
                    createBrandRatio.setUpdateTime(now);
                    createBrandRatio.setRatioType(BaseBrandRatioTypeEnum.BRANDRATIO.getCode());
                    brandRatioService.insert(createBrandRatio);
                }
            } else {
                if (brandRatioB.getRatio() == null && brandRatioVo.getBrandProjectToBeEffectiveRatio() == null) {
                    brandRatioService.deleteByPrimaryKey(brandRatioB.getRatioId());
                } else {
                    brandRatioB.setToBeEffectiveRatio(brandRatioVo.getBrandProjectToBeEffectiveRatio());
                    brandRatioB.setEffectiveDate(brandRatioVo.getEffectiveDate());
                    brandRatioB.setUpdateTime(DateUtil.getNow());
                    brandRatioB.setUpdater(mcStaffName);
                    brandRatioService.updateByKey(brandRatioB);
                }
            }

            return brandRatioVo.getBrandId();
        } catch (Exception ex) {
            logger.error("[zmn]新增/修改品牌系数失败, brandRatio:{}, ex:{}", brandRatioVo, ex.getMessage(), ex);
            throw new PlatException("操作失败！");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addEditCategoryRatio(String mcStaffName, BrandRatioModifyVo brandRatioModifyVo) throws PlatException {
        Date now = DateUtil.getNow();
        Integer brandId = brandRatioModifyVo.getCategOneBrandRatio().getBrandId();
        Integer priceType = brandRatioModifyVo.getCategOneBrandRatio().getPriceType();
        Integer bizType = brandRatioModifyVo.getCategOneBrandRatio().getBizType();
        Integer servCategId = brandRatioModifyVo.getCategOneBrandRatio().getServCategId();
        Integer categOneId = brandRatioModifyVo.getCategOneBrandRatio().getCategOneId();
        BrandRatio categOneRatioResult = null;
        BrandRatioQuery query = new BrandRatioQuery();
        query.setBrandId(brandId);
        query.setServCategId(servCategId);
        query.setBizType(bizType);
        query.setPriceType(priceType);
        query.setCategOneId(categOneId);
        query.setRatioType(BaseBrandRatioTypeEnum.BRANDCATEGONERATIO.getCode());
        List<BrandRatio> categOneRatios = brandRatioService.listByQuery(query);
        if (categOneRatios != null && categOneRatios.size() > 0) {
            categOneRatioResult = categOneRatios.get(0);
        }
        Double categOneRatio = brandRatioModifyVo.getCategOneBrandRatio().getToBeEffectiveRatio();

        // 处理一级分类系数
        if (categOneRatioResult == null) {
            if (categOneRatio != null) {
                BrandRatio createOneRatio = new BrandRatio();
                createOneRatio = brandRatioModifyVo.getCategOneBrandRatio();
                createOneRatio.setCreater(mcStaffName);
                createOneRatio.setUpdater(mcStaffName);
                createOneRatio.setCreateTime(now);
                createOneRatio.setUpdateTime(now);
                createOneRatio.setRatioType(BaseBrandRatioTypeEnum.BRANDCATEGONERATIO.getCode());
                brandRatioService.insert(createOneRatio);
            }
        } else {
            if (categOneRatioResult.getRatio() == null && categOneRatio == null) {
                brandRatioService.deleteByPrimaryKey(categOneRatioResult.getRatioId());
            } else {
                categOneRatioResult.setToBeEffectiveRatio(categOneRatio);
                categOneRatioResult.setEffectiveDate(brandRatioModifyVo.getCategOneBrandRatio().getEffectiveDate());
                categOneRatioResult.setUpdateTime(DateUtil.getNow());
                categOneRatioResult.setUpdater(mcStaffName);
                brandRatioService.updateByKey(categOneRatioResult);
            }
        }

        // 处理二级分类系数
        query.setRatioType(BaseBrandRatioTypeEnum.BRANDCATEGTWORATIO.getCode());
        List<BrandRatio> dbCategTwoRatios = brandRatioService.listByQuery(query);

        BrandRatioQuery brandRatioQuery = new BrandRatioQuery();
        BeanUtils.copyProperties(query, brandRatioQuery);
        List<BrandRatio> categTwoRatios = brandRatioModifyVo.getCategTwoBrandRatioList();
        List<BrandRatio> insertRatioList = new ArrayList<>();
        List<Integer> deleteRatioList = new ArrayList<>();
        List<BrandRatio> updateRatioList = new ArrayList<>();
        if (categTwoRatios != null && categTwoRatios.size() > 0) {
            categTwoRatios.forEach(e -> {
                brandRatioQuery.setCategId(e.getCategId());
                BrandRatio dbRatio = findBrandRatioByQueryOfCategTwoRatioList(brandRatioQuery, dbCategTwoRatios);

                if (dbRatio == null) {
                    if (e.getToBeEffectiveRatio() != null) {
                        e.setRatioType(BaseBrandRatioTypeEnum.BRANDCATEGTWORATIO.getCode());
                        e.setCreater(mcStaffName);
                        e.setUpdater(mcStaffName);
                        e.setCreateTime(now);
                        e.setUpdateTime(now);
                        insertRatioList.add(e);
                    }
                } else {
                    if (dbRatio.getRatio() == null && e.getToBeEffectiveRatio() == null) {
                        deleteRatioList.add(dbRatio.getRatioId());
                    } else {
                        e.setUpdateTime(DateUtil.getNow());
                        e.setUpdater(mcStaffName);
                        e.setRatioId(dbRatio.getRatioId());
                        updateRatioList.add(e);
                    }
                }
            });

            if (CollectionUtil.isNotNullOrEmpty(insertRatioList)) {
                brandRatioService.insertBatch(insertRatioList);
            }
            if (CollectionUtil.isNotNullOrEmpty(deleteRatioList)) {
                brandRatioService.deleteByKeys(deleteRatioList);
            }
            if (CollectionUtil.isNotNullOrEmpty(updateRatioList)) {
                brandRatioService.updateToBeEffectiveRatioBatch(updateRatioList);
            }
        }
    }

    @Override
    @SuppressWarnings("Duplicates")
    public BrandFactorCategoryRatioVo findByBrandIdAndServCategId(int brandId, int priceType, int servCategId, int bizType, String brandName) {
        BrandRatioQuery brandRatioQuery = new BrandRatioQuery();
        brandRatioQuery.setBrandId(brandId);
        brandRatioQuery.setBizType(bizType);
        brandRatioQuery.setRatioType(BaseBrandRatioTypeEnum.BRANDCATEGONERATIO.getCode());
        brandRatioQuery.setPriceType(priceType);
        brandRatioQuery.setServCategId(servCategId);

        List<ServCategory> servCategoryList = servAssCategoryService.findServCategoryByBrandIdAndShowType(brandId, ProductConsts.ERP_PRODUCT_TYPE);

        // 第一次默认进页面 没有servCategId 则取符合数据的第一个服务分类ID
        String servCategName = "";
        if (servCategId == 0) {
            if (CollectionUtil.isNotNullOrEmpty(servCategoryList)) {
                ServCategory servCategory = servCategoryList.get(0);
                brandRatioQuery.setServCategId(servCategory.getCategId());
                servCategName = servCategory.getName();
            }
        } else {
            ServCategory servCategory = servCategoryService.findByKey(servCategId);
            servCategName = servCategory.getName();
        }

        List<BrandRatio> brandLevelOneRatioVos = brandRatioService.listByQuery(brandRatioQuery);
        brandRatioQuery.setRatioType(BaseBrandRatioTypeEnum.BRANDCATEGTWORATIO.getCode());
        List<BrandRatio> brandLevelTwoRatioVos = brandRatioService.listByQuery(brandRatioQuery);

        // 分类系数配置需根据品牌与前台产品分类的关联关系，以及前后台服务品类关联关系，过滤可配置系数的后台服务分类与产品分类
        List<BaseCategory> categTwos = servAssCategoryService.findCategoryTwoByServIdAndBrandIdAndShowType(brandRatioQuery.getServCategId(), brandId, ProductConsts.ERP_PRODUCT_TYPE);
        Map<Integer, List<BaseCategory>> map = categTwos.stream().collect(Collectors.groupingBy(BaseCategory::getParentId));
        Map<Integer, List<BrandRatioVo>> levelTwoRatioMap = new HashMap<>();
        for (Map.Entry<Integer, List<BaseCategory>> entry : map.entrySet()) {
            List<BrandRatioVo> resultList = new ArrayList<>();
            if (entry.getValue() != null) {
                for (BaseCategory baseCategory : entry.getValue()) {
                    BrandRatioVo brandLevelTwoRatioVo = new BrandRatioVo();
                    brandLevelTwoRatioVo.setBrandId(brandId);
                    brandLevelTwoRatioVo.setCategOneId(entry.getKey());
                    brandLevelTwoRatioVo.setCategId(baseCategory.getCategId());
                    brandLevelTwoRatioVo.setCategName(baseCategory.getName());
                    for (BrandRatio inner : brandLevelTwoRatioVos) {
                        if (inner.getCategId().equals(baseCategory.getCategId()) && inner.getCategOneId().equals(baseCategory.getParentId())) {
                            brandLevelTwoRatioVo.setRatio(inner.getRatio());
                            brandLevelTwoRatioVo.setToBeEffectiveRatio(inner.getToBeEffectiveRatio());
                        }
                    }
                    resultList.add(brandLevelTwoRatioVo);
                }
            }
            levelTwoRatioMap.put(entry.getKey(), resultList);
        }

        List<Integer> categOneIds = categTwos.stream().map(e -> e.getParentId()).distinct().collect(Collectors.toList());
        List<BaseCategory> categOnes = new ArrayList<>();
        if (CollectionUtil.isNotNullOrEmpty(categOneIds)) {
            categOnes = baseCategoryService.findByKeys(categOneIds);
        }

        List<BrandRatioVo> constructVo = new ArrayList<>();
        for (BaseCategory baseCategory : categOnes) {
            BrandRatioVo brandLevelOneRatioVo = new BrandRatioVo();
            brandLevelOneRatioVo.setCategOneId(baseCategory.getCategId());
            brandLevelOneRatioVo.setCategName(baseCategory.getName());
            constructVo.add(brandLevelOneRatioVo);
        }

        for (BrandRatioVo brandLevelOneRatioVo : constructVo) {
            for (BrandRatio inner : brandLevelOneRatioVos) {
                if (brandLevelOneRatioVo.getCategOneId().equals(inner.getCategOneId())) {
                    brandLevelOneRatioVo.setRatio(inner.getRatio());
                    brandLevelOneRatioVo.setToBeEffectiveRatio(inner.getToBeEffectiveRatio());
                }
            }
        }

        BrandFactorCategoryRatioVo brandFactorCategoryRatioVo = new BrandFactorCategoryRatioVo();
        brandFactorCategoryRatioVo.setServCategId(brandRatioQuery.getServCategId());
        brandFactorCategoryRatioVo.setServCategName(servCategName);
        brandFactorCategoryRatioVo.setServCategories(servCategoryList);
        brandFactorCategoryRatioVo.setBrandLevelOneRatioVos(constructVo);
        brandFactorCategoryRatioVo.setMap(levelTwoRatioMap);

        return brandFactorCategoryRatioVo;
    }

    @Override
    public List<BrandRatioVo> listBrandLevelTwoRatioVo(BrandRatioQuery query) {
        List<BrandRatio> brandLevelTwoRatioVos = brandRatioService.listByQuery(query);
        List<BaseCategory> categTwos = servAssCategoryService.findCategoryTwoByServIdAndShowType(query.getServCategId(), ProductConsts.ERP_PRODUCT_TYPE);
        Map<Integer, List<BaseCategory>> map = categTwos.stream().collect(Collectors.groupingBy(BaseCategory::getParentId));

        List<BrandRatioVo> resultList = new ArrayList<>();
        if (map.get(query.getCategOneId()) != null) {
            for (BaseCategory baseCategory : map.get(query.getCategOneId())) {
                BrandRatioVo brandLevelTwoRatioVo = new BrandRatioVo();
                brandLevelTwoRatioVo.setBrandId(query.getBrandId());
                brandLevelTwoRatioVo.setCategOneId(query.getCategOneId());
                brandLevelTwoRatioVo.setCategId(baseCategory.getCategId());
                brandLevelTwoRatioVo.setCategName(baseCategory.getName());
                for (BrandRatio inner : brandLevelTwoRatioVos) {
                    if (inner.getCategId().equals(baseCategory.getCategId()) && inner.getCategOneId().equals(baseCategory.getParentId())) {
                        brandLevelTwoRatioVo.setRatio(inner.getRatio());
                        brandLevelTwoRatioVo.setToBeEffectiveRatio(inner.getToBeEffectiveRatio());
                    }
                }
                resultList.add(brandLevelTwoRatioVo);
            }
        }

        return resultList;
    }

    /**
     * 功能描述 ：数据不存在返回默认系数null
     *
     * @param product
     * @param brandId
     * @param type
     * @return com.zmn.plat.model.vo.brand.FaultTariffBrandRatioVo
     * @author tanbiao
     * @modifier
     * @since 2019/11/21
     */
    private BrandFactorVo defaultRatio(ServProduct product, Integer brandId, Integer type) {
        BrandFactorVo vo = new BrandFactorVo();
        vo.setRatio(null);
        vo.setBrandId(brandId);
        vo.setType(type);
        vo.setProductId(product.getProductId());
        vo.setCategTwoId(product.getCategId());
        vo.setCategOneId(product.getCategOneId());
        vo.setServCategId(product.getServCategId());
        return vo;
    }

    private BrandRatio findBrandRatioByBrandIdAndPriceTypeAndBizType(Integer brandId, Integer priceType, Integer bizType) {
        BrandRatioQuery brandRatioQuery = new BrandRatioQuery();
        brandRatioQuery.setBrandId(brandId);
        brandRatioQuery.setRatioType(BaseBrandRatioTypeEnum.BRANDRATIO.getCode());
        brandRatioQuery.setBizType(bizType);
        brandRatioQuery.setPriceType(priceType);
        List<BrandRatio> brandRatios = brandRatioService.listByQuery(brandRatioQuery);
        BrandRatio brandRatio = null;
        if (brandRatios != null && brandRatios.size() > 0) {
            brandRatio = brandRatios.get(0);
        }

        return brandRatio;
    }

    @SuppressWarnings("Duplicates")
    private BrandRatio findBrandRatioByQueryOfCategTwoRatioList(BrandRatioQuery brandRatioQuery, List<BrandRatio> categTwoRatioList) {
        BrandRatio brandRatio;
        for (int i = 0; i < categTwoRatioList.size(); i++) {
            brandRatio = categTwoRatioList.get(i);
            if (Objects.equals(brandRatioQuery.getBrandId(), brandRatio.getBrandId()) && Objects.equals(brandRatioQuery.getServCategId(), brandRatioQuery.getServCategId())
                    && Objects.equals(brandRatioQuery.getCategOneId(), brandRatio.getCategOneId()) && Objects.equals(brandRatioQuery.getCategId(), brandRatio.getCategId())
                    && Objects.equals(brandRatioQuery.getBizType(), brandRatio.getBizType()) && Objects.equals(brandRatioQuery.getPriceType(), brandRatio.getPriceType())
                    && Objects.equals(brandRatioQuery.getRatioType(), brandRatio.getRatioType())) {
                return brandRatio;
            }
        }
        return null;
    }
}
